package com.zmn.plat.business.impl.orderconfig.distribute;

import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.utils.date.DateUtil;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.common.utils.string.StringUtil;
import com.zmn.mcc.common.constant.DpermitConsts;
import com.zmn.plat.business.interfaces.orderconfig.distribute.DistributeWeightPlatBService;
import com.zmn.plat.common.dto.orderconfig.distribute.RobOrderDIO;
import com.zmn.plat.common.exception.ParamOutOfRangeException;
import com.zmn.plat.dubbo.constant.DistributeConsts;
import com.zmn.plat.model.entity.area.BaseArea;
import com.zmn.plat.model.entity.orderconfig.distribute.*;
import com.zmn.plat.services.interfaces.area.BaseAreaService;
import com.zmn.plat.services.interfaces.orderconfig.distribute.DistributeWeightPlatService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 描述：派单配置业务服务 -- 实现类
 *
 * @author: Yangk
 * @since : 2021年1月27日
 */
@Slf4j
@Service
public class DistributeWeightPlatBServiceImpl implements DistributeWeightPlatBService {

    @Resource
    DistributeWeightPlatService distributeWeightPlatService;

    @Resource
    BaseAreaService baseAreaService;

    @Override
    public DistributeWeightPlat findByKey(Integer distributePlatId) {
        if (NumberUtil.isNullOrZero(distributePlatId)) {
            log.error("#DistributeWeightPlatBService#findByPlatAndBizType# find service provider order config failed! " +
                    "reason: {}, distributePlatId: {}", "distributePlatId is null!", distributePlatId);
            return null;
        } else {
            return distributeWeightPlatService.findByKey(distributePlatId);
        }
    }

    @Override
    public DistributeWeightPlat findServiceProviderConfigByPlatAndBizType(Integer plat, Integer bizType) {

        List<DistributeWeightPlat> distributeWeightPlatList = distributeWeightPlatService.findByPlatAndBizType(plat, bizType, DistributeConsts.DISTRIBUTE_SERVICE_PROVIDER);
        if (distributeWeightPlatList.size() > GlobalConsts.NONE) {
            return distributeWeightPlatList.get(GlobalConsts.NONE);
        } else {
            log.error("#DistributeWeightPlatBService#findByPlatAndBizType# find service provider order config failed! " +
                    "reason: {}, plat: {}, bizType: {}", "there is no result from db!", plat, bizType);
            return null;
        }
    }

    @Override
    public List<DistributeWeightPlat> listServiceProviderConfigByPlatIdAndBizType(List<Integer> platList, Integer bizType) {

        List<DistributeWeightPlat> distributeWeightPlatList = distributeWeightPlatService.listByPlatIdAndBizType(platList, bizType, DistributeConsts.DISTRIBUTE_SERVICE_PROVIDER);
        return distributeWeightPlatList;
    }

    @Override
    public DistributeWeightPlat findPlatDirectlyConfigByPlatAndBizTypeAndCityId(Integer plat, Integer bizType, Integer cityId) {

        List<DistributeWeightPlat> distributeWeightPlatList = distributeWeightPlatService.findByPlatAndBizTypeAndCity(
                plat, bizType, cityId, DistributeConsts.DISTRIBUTE_PLAT_DIRECTLY);
        if (distributeWeightPlatList.size() > GlobalConsts.NONE) {
            return distributeWeightPlatList.get(GlobalConsts.NONE);
        } else {
            log.error("#DistributeWeightPlatBService#findByPlatAndBizType# find plat directly config failed! " +
                    "reason: {}, plat: {}, bizType: {}", "there is no result from db!", plat, bizType);
            return null;
        }
    }

    @Override
    public List<DistributeWeightPlat> listPlatDirectlyConfigByPlatIdAndBizType(List<Integer> platList, Integer bizType) {
        List<DistributeWeightPlat> distributeWeightPlatList = distributeWeightPlatService.listByPlatIdAndBizType(platList, bizType, DistributeConsts.DISTRIBUTE_PLAT_DIRECTLY);
        return distributeWeightPlatList;
    }

    @Override
    public Integer updateByKey(DistributeWeightPlat distributeWeightPlat) {
        return distributeWeightPlatService.updateByKey(distributeWeightPlat);
    }

    @Override
    public Integer updateStatusByQuery(DistributeWeightStatusQuery query) {
        return distributeWeightPlatService.updateStatusByQuery(query);
    }

    @Override
    public Integer updateStatus(UpdateStatusQuery updateStatusQuery) {
        if (Objects.isNull(updateStatusQuery)) {
            log.error("#DistributeWeightPlatBService#updateStatus# update failed! reason: {}", "query is null");
            throw new ParamOutOfRangeException("query is null");
        }
        if (Objects.isNull(updateStatusQuery.getIdList())) {
            log.error("#DistributeWeightPlatBService#updateStatus# update failed! reason: {} query: {}", "idList is null", updateStatusQuery);
            throw new ParamOutOfRangeException("idList is null");
        }
        if (NumberUtil.isNullOrZero(updateStatusQuery.getStatus())) {
            log.error("#DistributeWeightPlatBService#updateStatus# update failed! reason: {} query: {}", "status is null", updateStatusQuery);
            throw new ParamOutOfRangeException("status is null");
        }
        if (StringUtil.isBlank(updateStatusQuery.getUpdater())) {
            updateStatusQuery.setUpdater("system");
        }
        if (Objects.isNull(updateStatusQuery.getUpdateTime())) {
            updateStatusQuery.setUpdateTime(DateUtil.getNow());
        }
        return distributeWeightPlatService.updateStatus(updateStatusQuery);
    }

    @Override
    public Integer insert(DistributeWeightPlat distributeWeightPlat) {
        return distributeWeightPlatService.insert(distributeWeightPlat);
    }

    @Override
    public List<DistributeWeightAreaVO> listProvince(Integer selectedValue) {
        List<BaseArea> baseAreaList =
                baseAreaService.listAboveByLevel(DpermitConsts.AREA_LEVEL_PROVINCE, GlobalConsts.YES);
        return this.parseAreaToVO(baseAreaList, selectedValue);
    }

    @Override
    public List<DistributeWeightAreaVO> listCityByProvince(SearchCityQuery searchCityQuery) {
        if (Objects.isNull(searchCityQuery) || NumberUtil.isNullOrZero(searchCityQuery.getProvinceId())) {
            // 如果没有传省ID 返回空列表
            return new ArrayList<>();
        }
        List<BaseArea> baseAreaList = baseAreaService.listByParentId(searchCityQuery.getProvinceId());
        // 过滤掉已选择的城市
        CheckCityAvailableQuery query =
                CheckCityAvailableQuery.builder()
                        .distributePlatId(searchCityQuery.getDistributePlatId())
                        .bizType(searchCityQuery.getBizType())
                        .plat(searchCityQuery.getPlat())
                        .provinceId(searchCityQuery.getProvinceId())
                        .build();
        List<Integer> beenSetCityIdList = distributeWeightPlatService.hasBeenSetCity(query);
        List<BaseArea> result = baseAreaList.stream()
                .filter(item -> !beenSetCityIdList.contains(item.getAreaId()))
                .collect(Collectors.toList());
        return this.parseAreaToVO(result, searchCityQuery.getSelectedValue());
    }

    @Override
    public DistributeWeightPlat findPlatDirectlyConfigByQuery(RobOrderDIO robOrderDIO) {

        List<DistributeWeightPlat> distributeWeightPlatList = distributeWeightPlatService.findPlatDirectlyConfigByQuery(robOrderDIO);
        if (distributeWeightPlatList.size() > GlobalConsts.NONE) {
            return distributeWeightPlatList.get(GlobalConsts.NONE);
        } else {
            log.error("#DistributeWeightPlatBService#findPlatDirectlyConfigByQuery# find plat directly config failed! " +
                    "reason: {}, plat: {}, bizType: {}", "there is no result from db!",robOrderDIO);
            return null;
        }
    }

    /**
     * 将区域对象转换称下拉框识别的VO对象
     *
     * @param baseAreaList
     * @return
     */
    private List<DistributeWeightAreaVO> parseAreaToVO(List<BaseArea> baseAreaList, Integer selectedValue) {
        List<DistributeWeightAreaVO> distributeWeightAreaVOList = new ArrayList<>();
        for (BaseArea baseArea : baseAreaList
        ) {
            DistributeWeightAreaVO distributeWeightAreaVO = DistributeWeightAreaVO.builder()
                    .value(baseArea.getAreaId())
                    .name(baseArea.getName())
                    .selected(Objects.equals(baseArea.getAreaId(), selectedValue))
                    .disabled(false)
                    .build();
            distributeWeightAreaVOList.add(distributeWeightAreaVO);
        }
        return distributeWeightAreaVOList;
    }

}
